#pragma once
#include "dll_export.h"
#include <boost/thread.hpp>
#include <string>
#include <vector>
#include <deque>

LUA_DEBUG_BEGIN

typedef boost::recursive_mutex              thread_mutex;
typedef boost::recursive_mutex::scoped_lock scoped_lock;
typedef std::vector<std::string>            string_array;

/**
* @brief It's a thread safe queue class.
*/
template<class Ty, class Container=std::deque<Ty> >
class queue_mt
{
public:
    typedef typename Container::value_type      value_type;
    typedef typename Container::size_type       size_type;
    typedef typename Container::pointer         pointer;
    typedef typename Container::const_pointer   const_pointer;
    typedef typename Container::reference       reference;
    typedef typename Container::const_reference const_reference;

private:
    mutable thread_mutex m_mutex;

public:
    Container c;

public:
    explicit queue_mt() {
    }

    ~queue_mt() {
    }

    void push(const value_type &val) {
        scoped_lock lock(m_mutex);
        this->c.push_back(val);
    }

    void pop() {
        scoped_lock lock(m_mutex);
        this->c.pop_front();
    }

    bool empty() const {
        scoped_lock lock(m_mutex);
        return this->c.empty();
    }

    size_type size() const {
        scoped_lock lock(m_mutex);
        return this->c.size();
    }

    reference back() {
        scoped_lock lock(m_mutex);
        return this->c.back();
    }

    const_reference back() const {
        scoped_lock lock(m_mutex);
        return this->c.back();
    }

    reference front() {
        scoped_lock lock(m_mutex);
        return this->c.front();
    }

    const_reference front() const {
        scoped_lock lock(m_mutex);
        return this->c.front();
    }
};

LUA_DEBUG_END
